package com.example.librarymanagementproject2.Common.filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Map;

/**
 * @ClassName TokenFilter
 * @Description 令牌过滤器
 * @Author Kx
 * @Date 2025/10/9 11:35
 * @Version 1.0
 */
@Component
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {
    private final static String TOKEN_KEY = "user_token:";

    @Autowired
    private RedisTemplate<String, Object> redisTemplate; // redis缓存对象
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 强制转换成 Http 相关的子类，以便使用 HTTP 特有的功能
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 判断是否是登录或注册接口
        if (request.getRequestURI().contains("/users") || request.getRequestURI().contains("/login") || request.getRequestURI().startsWith("/sendEmail/")) {
            // 放行
            filterChain.doFilter(request, response);
            return;
        }

        // 从请求头获取 UUID 令牌
        String token = request.getHeader("Authorization");
        if (StringUtils.hasText(token) && token.startsWith("Bearer ")) {
            token = token.substring(7).trim(); // 去除"Bearer "前缀，得到纯UUID令牌
        }

        // 判断令牌是否为空
        if (!StringUtils.hasText(token)) {
            response.setStatus(401);
            response.getWriter().write("令牌不能为空");
            return;
        }

        // 验证令牌
        // 获取令牌
        String redisKey = TOKEN_KEY + token;
        Object userToken = redisTemplate.opsForValue().get(redisKey);
        if (userToken == null) {
            response.setStatus(401);
            response.getWriter().write("令牌无效或已过期，请重新登录");
            return;
        }

        // 如果令牌有效，则将用户信息存储在请求中
        Map<String, Object> userMap = (Map<String, Object>) userToken;
        request.setAttribute("userId", userMap.get("id"));
        request.setAttribute("username", userMap.get("username"));
        request.setAttribute("role", userMap.get("role"));

        // 如果令牌有效，则放行
        filterChain.doFilter(request, response);
    }
}
